<template>
	<div
		v-if="workflowStore.state.nodeMenu.visible"
		class="node-panel"
		:style="{
			position: 'fixed',
			top: `${workflowStore.state.nodeMenu.position.y}px`,
			left: `${workflowStore.state.nodeMenu.position.x}px`,
			zIndex: 99999,
		}"
		@click.stop
		@contextmenu.prevent
	>
		<div class="panel-header">
			<div>
				<span>蓝图所有操作</span>
			</div>
		</div>
		<div class="panel-content">
			<div style="height: 28px;">
				<el-input
				  v-model="keywords"
				  size="small"
				  placeholder="搜索"
				  :prefix-icon="Search"
				/>
			</div>
			<div style="background-color: #181818;overflow: hidden;">
				<el-scrollbar height="333">
					<el-tree
						:data="filteredCategories"
						:props="defaultProps"
						node-key="id"
						:highlight-current="true"
						:expand-on-click-node="true"
						@node-click="handleNodeClick"
						ref="treeRef"
						:default-expanded-keys="expandedKeys"
					>
						<template #default="{ node, data }">
							<div class="custom-tree-node">
								<template v-if="!data.isLeaf">
									
									<div v-if="data.children && data.children.length>0">
										<el-icon class="node-icon" size="16" style="color: white;" v-if="data.icon && data.icon.startsWith('el-icon')">
											<component :is="data.icon.replace('el-icon-', '')" />
										</el-icon>
										<svg-icon v-else-if="data.icon" :icon-class="data.icon" class="node-icon" size="16" style="color: white;" />
										<span>{{ data.name || data.label  }}</span>
									</div>
									
									<div v-else style="display: flex;justify-content: flex-start;align-items: center;width: 100%;">
										<el-icon class="node-icon" size="16" style="color: white;" v-if="data.icon && data.icon.startsWith('el-icon')">
											<component :is="data.icon.replace('el-icon-', '')" />
										</el-icon>
										<svg-icon v-else-if="data.icon" :icon-class="data.icon" class="node-icon" size="16" style="color: white;" />
										<span>{{ data.name || data.label  }}</span>
									</div>
									
									
								</template>
								<template v-else>
									<el-icon class="node-icon" size="16" style="color: white;" v-if="data.icon && data.icon.startsWith('el-icon')">
										<component :is="data.icon.replace('el-icon-', '')" />
									</el-icon>
									<svg-icon v-else-if="data.icon" :icon-class="data.icon" class="node-icon" size="16" style="color: white;" />
									<span>{{ data.name || data.label  }}</span>
								</template>
							</div>
						</template>
					</el-tree>
				</el-scrollbar>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
	import { Search } from '@element-plus/icons-vue'
	import { ref, watch, onMounted, computed } from 'vue';
	import { useWorkflowStore } from '@/stores/workflow';
	import BlueprintNodeAPI from '@/api/biz/blueprintnode';
	import type { NodeType } from '@/views/data-manage/workflow/components/types';
	
	const props = defineProps<{
	  svgContainer: SVGSVGElement;
	}>();
	
	const workflowStore = useWorkflowStore();
	const treeRef = ref();
	const expandedKeys = ref<string[]>([]);
	
	// 定义事件
	const emit = defineEmits<{
	  (e: 'add-node', nodeType: NodeType): void;
	}>();
	
	const handleNodeClick = (data: any, node: any) => {
	  // 如果是叶子节点，则添加到画布
	  if (!data.children || data.children.length === 0) {
	    handAddNode(node);
	  }
	};
	
	// 处理添加节点
	const handAddNode = (node: any) => {
	  // 构造节点类型数据
	  const nodeType: NodeType = {
		id: node.data.id,
		type: node.data.type || 'default',
		label: node.data.name || node.data.label,
		data: node.data.data || '{"inputs":[],"outputs":[]}',
		width: node.data.width || 200,
		color: node.data.color || '#409EFF',
		icon: node.data.icon || '',
		showHead: node.data.showHead || '1'
	  };
	  workflowStore.addNodeAtMenuPosition(nodeType,props.svgContainer);
	};
	
	const defaultProps = {
	  children: 'children',
	  label: 'name'
	}
	const keywords = ref<string>('');
	const categories = ref<any>();
	
	// 监听搜索关键字变化
	watch(keywords, (newValue) => {
	  if (newValue) {
	    // 搜索时收集需要展开的节点 ID
	    expandedKeys.value = getExpandedKeys(categories.value, newValue.toLowerCase());
	  } else {
	    // 清空搜索时折叠所有节点
	    expandedKeys.value = [];
	  }
	});
	
	// 递归收集需要展开的节点 ID
	const getExpandedKeys = (data: any[], searchText: string): string[] => {
	  if (!data) return [];
	  
	  const keys: string[] = [];
	  
	  const collect = (nodes: any[], parentMatched = false) => {
	    nodes.forEach(node => {
	      const currentMatched = (node.name || node.label || '').toLowerCase().includes(searchText);
	      
	      // 如果当前节点匹配或父节点匹配，添加当前节点 ID
	      if (currentMatched || parentMatched) {
	        keys.push(node.id);
	      }
	      
	      // 递归处理子节点
	      if (node.children && node.children.length) {
	        collect(node.children, currentMatched || parentMatched);
	      }
	      // 递归处理节点列表
	      if (node.nodes && node.nodes.length) {
	        collect(node.nodes, currentMatched || parentMatched);
	      }
	    });
	  };
	  collect(data);
	  return keys;
	};

	// 过滤后的树数据
	const filteredCategories = computed(() => {
	  if (!keywords.value) return categories.value;
	  return filterTree(JSON.parse(JSON.stringify(categories.value)));
	});
	
	// 递归过滤树
	const filterTree = (data: any[]) => {
	  if (!data) return [];
	  
	  return data.filter(node => {
	    // 转换为小写进行比较
	    const searchText = keywords.value?.toLowerCase() || '';
	    const nodeName = (node.name || node.label || '').toLowerCase();
	    
	    // 如果当前节点匹配，直接返回
	    if (nodeName.includes(searchText)) {
	      return true;
	    }
	    
	    // 如果有子节点，递归过滤
	    if (node.children && node.children.length) {
	      const filteredChildren = filterTree(node.children);
	      if (filteredChildren.length) {
	        node.children = filteredChildren;
	        return true;
	      }
	    }
	    
	    // 如果有节点列表，递归过滤
	    if (node.nodes && node.nodes.length) {
	      const filteredNodes = filterTree(node.nodes);
	      if (filteredNodes.length) {
	        node.nodes = filteredNodes;
	        return true;
	      }
	    }
	    
	    return false;
	  });
	};

	const getCategories = () => {
	  BlueprintNodeAPI.getCategories()
	  .then((data:any) => {
		  categories.value = recurOptions(data,'-1');
	  })
	  .finally(() => {
	  });
	}
	
	function recurOptions(list:any,rootId:string) {
	  function buildTree(node:any) {
		let children = []
		for (let item of list) {
		  if (item.parentId === node.id) {
			children.push(buildTree(item))
		  }
		}
		if (children.length > 0) {
		  node.children = children
		}
		
		if(node.nodes && node.nodes.length>0){
			node.children = node.nodes
		}
		
		return node
	  }
	  let res = []
	  for (let item of list) {
		  if(rootId){
			if (item.parentId === rootId) {
			  res.push(buildTree(item))
			}  
		  }else{
			  if (item.parentId === '-1' || item.parentId === '') {
				res.push(buildTree(item))
			  }
		  }
		
	  }
	  return res
	}
	
	onMounted(() => {
	  getCategories();
	});
</script>

<style lang="scss" scoped>
.node-panel {
    width: 384px;
    background-color: #474747;
    display: flex;
    flex-direction: column;
	height: 400px;
    overflow: hidden;
    :deep(.el-input) {
      .el-input__wrapper {
        background-color: #1a1a1a;
        box-shadow: none;
        border: none;
        
        &.is-focus {
          box-shadow: none;
        }
        
        .el-input__inner {
          color: #fff;
          
          &::placeholder {
            color: #666;
          }
        }
      }
    }

    .panel-header {
	  height: 30px;
	  padding-left: 10px;
	  display: flex;
	  align-items: center;
      span {
        color: #cccccc;
        font-size: 13px;
        font-weight: 500;
      }
    }

    .panel-content {
		flex: 1;
		overflow-y: hidden;
		padding: 4px;
        background-color: #252526;
		:deep(.el-tree) {
			--el-tree-node-hover-bg-color: transparent;
			--el-tree-node-content-height: 38px;
			--el-tree-expand-icon-color: #888;
			background-color: transparent !important;
			color: #e1e1e1;
			.el-tree-node {
				background-color: transparent !important;
				&.is-expanded {
					> .el-tree-node__content {
					  background-color: rgba(255, 255, 255, 0.04);
					}
				}

				.el-tree-node__expand-icon {
					color: var(--el-tree-expand-icon-color);

					&.expanded {
					  transform: rotate(90deg);
					}

					&.is-leaf {
					  color: transparent;
					}
				}

				.el-tree-node__content {
					height: var(--el-tree-node-content-height);
					padding: 0 16px;
					transition: all 0.2s ease;
					background-color: transparent !important;
					height: 25px;
					&:hover {
					  background-color: rgba(255, 255, 255, 0.06) !important;
					}
				}

				.el-tree-node__children {
					background-color: transparent !important;
					position: relative;

					// &::before {
					//   content: '';
					//   position: absolute;
					//   left: 24px;
					//   top: 0;
					//   width: 1px;
					//   height: 100%;
					//   background: rgba(255, 255, 255, 0.06);
					// }
				}
			}
		}

		.custom-tree-node {
			display: flex;
			align-items: center;
			gap: 8px;
			span {
			  color: #cccccc;
			  font-size: 12px;
			}
			.node-icon {
			  opacity: 0.8;
			}
		}
    }
  }
</style> 